package com.think.teaching.controller;

import com.think.common.controller.BaseController;
import com.think.common.model.Result;
import com.think.common.model.ResultCode;
import com.think.common.utils.Common;
import com.think.common.utils.JSonUtil;
import com.think.teaching.model.*;
import com.think.teaching.service.impl.*;
import com.think.teaching.utils.CourseState;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.apache.ibatis.annotations.Delete;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程 前端控制器
 * </p>
 *
 * @author think
 * @since 2020-08-12
 */
@Slf4j
@RestController
@RequestMapping("/v1")
@Api(tags =  "课程接口文档")
public class CourseController extends BaseController {
	private final TagServiceImpl tagService;

	private final CourseServiceImpl courseService;
	
	private final ChapterServiceImpl chapterServiceImpl;
	
	private final CourseTeacherServiceImpl courseTeacherService;
	
	private final TeacherInfoServiceImpl teacherService;
	
	private final ExamTestServiceImpl examTestServiceImpl;
	
	private final CourseNoticeServiceImpl courseNoticeServiceImpl;
	
	private final CourseMemberServiceImpl courseMemberServiceImpl;
	
	private final VrLessonDocumentServiceImpl vrLessonDocumentServiceImpl;
	
	private final VrLessonServiceImpl vrLessonServiceImpl;

	public CourseController(CourseServiceImpl courseService,
			ChapterServiceImpl chapterServiceImpl, 
			CourseTeacherServiceImpl courseTeacherService, 
			TeacherInfoServiceImpl teacherService,
			ExamTestServiceImpl examTestServiceImpl,
			CourseNoticeServiceImpl courseNoticeServiceImpl,
			TagServiceImpl tagService, CourseMemberServiceImpl courseMemberServiceImpl, VrLessonDocumentServiceImpl vrLessonDocumentServiceImpl, VrLessonServiceImpl vrLessonServiceImpl) {
		this.courseService = courseService;
		this.chapterServiceImpl = chapterServiceImpl;
		this.courseTeacherService = courseTeacherService;
		this.teacherService = teacherService;
		this.examTestServiceImpl = examTestServiceImpl;
		this.courseNoticeServiceImpl = courseNoticeServiceImpl;
		this.tagService=tagService;
		this.courseMemberServiceImpl = courseMemberServiceImpl;
		this.vrLessonDocumentServiceImpl = vrLessonDocumentServiceImpl;
		this.vrLessonServiceImpl = vrLessonServiceImpl;
	}

	@ApiOperation("添加新的课程")
	@PostMapping("admin/course")
	public Result AddNewCourse(@RequestBody()Course data) {
		Result result = data.CheckObjectComplete();
		if(result.getCode() == ResultCode.SUCCESS.code()) {
			Course course =null;
			data.setState(CourseState.WAITING_SUBMIT.getValue());
			data.setCreatedBy(Common.GetCurrentAuthor().getUserId());
			try {
				course = courseService.AddCourse(data);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if( course!= null) {
				return Result.success(course);
			}
			else {
				return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
			}
		}
		else
			return result;
	}
	
	@ApiOperation("更新课程")
	@RequestMapping(value = "admin/course/update",method = RequestMethod.POST)
	public Result UpdateNewCourse(@RequestBody()Course data) {
		Result result = data.CheckObjectComplete();
		Course course = courseService.getById(data.getId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		if(result.getCode() == ResultCode.SUCCESS.code()) {
			try {
				data.setExamStandard(course.getExamStandard());
				data.setCourseDesign(course.getCourseDesign());
				data.setState(CourseState.WAITING_SUBMIT.getValue());
				course = courseService.UpdateCourse(data);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if( course!= null) {
				return Result.success(course);
			}
			else {
				return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
			}
		}
		else
			return result;
	}
	
	@ApiOperation("删除课程")
	@RequestMapping(value = "admin/course/del/{id}",method = RequestMethod.POST)
	public Result DeleteCourse(@PathVariable("id")Integer id) {
		Course course = courseService.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			if (courseService.DeleteObjectById(id)) {
				return Result.success();
			}
			return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
		}
	}
	
	@ApiOperation("修改课程设计")
	@RequestMapping(value = "admin/course/courseDesign",method = RequestMethod.POST)
	public Result UpdateCourseDesign(@RequestBody()Course data) {
		Course course = courseService.getById(data.getId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			try {
				course.setCourseDesign(data.getCourseDesign());
				data.setState(CourseState.WAITING_SUBMIT.getValue());
				course = courseService.UpdateCourse(data);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if( course!= null) {
				return Result.success(course);
			}
			else {
				return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
			}
		}
	}
	
	@ApiOperation("修改考试标准")
	@RequestMapping(value = "admin/course/examStandard",method = RequestMethod.POST)
	public Result UpdateExamStandard(@RequestBody()Course data) {
		Course course = courseService.getById(data.getId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			try {
				course.setExamStandard(data.getExamStandard());
				data.setState(CourseState.WAITING_SUBMIT.getValue());
				course = courseService.UpdateCourse(data);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if( course!= null) {
				return Result.success(course);
			}
			else {
				return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
			}
		}
	}
	
	@ApiOperation("管理员获取课程详情")
	@RequestMapping(value = "admin/course/{id}",method = RequestMethod.GET)
	public Result GetCourse(@PathVariable("id")Integer id) {
		Course course = courseService.GetCourse(id,0,0);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			
			return Result.success(course);
		}
	}
	
	@ApiOperation("用户获取课程详情")
	@RequestMapping(value = "open/course/{id}",method = RequestMethod.GET)
	public Result UserGetCourse(@PathVariable("id")Integer id) {
		Course course = courseService.GetCourse(id,0,1);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			
			return Result.success(course);
		}
	}
	
	@ApiOperation("管理员修改课程状态")
	@RequestMapping(value = "admin/course/{id}/{state}",method = RequestMethod.POST)
	public Result UpdateCourseState(@PathVariable("id")Integer id,@PathVariable("state")Integer state) {
		Course course = courseService.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			try {
				course = courseService.SetCourseState(id, state);
				return Result.success(course);
			} catch (Exception e) {
				return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
			}
		}
	}
	
	@ApiOperation("用户搜索获取课程")
	@RequestMapping(value = "open/course/search",method = RequestMethod.GET)
	public Result UserSearchCourse(@RequestParam("key")String key) {
		return Result.success(courseService.SearchCourseWithKey(key, true));
	}
	
	@ApiOperation("管理员搜索获取课程")
	@RequestMapping(value = "admin/course/search",method = RequestMethod.GET)
	public Result AdminSearchCourse(@RequestParam("key")String key) {
		return Result.success(courseService.SearchCourseWithKey(key, false));
	}
	
	@ApiOperation("管理员获取课程列表")
	@RequestMapping(value = "admin/courses/{page}/{count}",method = RequestMethod.GET)
	public Result AdminListCourse(@PathVariable("page")Integer page,@PathVariable("count")Integer count,
			@RequestParam(value = "type",required = false,defaultValue = "0") Integer type,
			@RequestParam(value = "mode",required = false,defaultValue = "0") Integer mode,
			@RequestParam(value = "tag",required = false,defaultValue = "0") Integer tag,
			@RequestParam(value = "state",required = false,defaultValue = "-1") Integer state) {
		if(Common.IsRootAdmin() || Common.HasRole("ROLE_COURSE")|| Common.HasRole("ROLE_TEACHING")) {
			return Result.success(courseService.ListCourseWithTagAndType(count, page,type,0,mode,
					state,tag,0));
		}
		return Result.success(courseService.ListCourseWithTagAndType(count, page,type,0,mode,
				state,tag,Common.GetCurrentAuthor().getUserId()));
	}
	
	@ApiOperation("管理员获取课程列表")
	@RequestMapping(value = "admin/courses/info/{page}/{count}",method = RequestMethod.GET)
	public Result AdminListCourseBase(@PathVariable("page")Integer page,@PathVariable("count")Integer count,
			@RequestParam(value = "type",required = false,defaultValue = "0") Integer type,
			@RequestParam(value = "mode",required = false,defaultValue = "0") Integer mode,
			@RequestParam(value = "tag",required = false,defaultValue = "0") Integer tag,
			@RequestParam(value = "state",required = false,defaultValue = "-1") Integer state) {
		return Result.success(courseService.ListCourseWithTagAndType(count, page,type,0,mode,
				state,tag,0));
	}
	
	@ApiOperation("用户获取课程列表")
	@RequestMapping(value = "open/courses/{page}/{count}",method = RequestMethod.GET)
	public Result UserListCourse(@PathVariable("page")Integer page,
								 @PathVariable("count")Integer count,@RequestParam(required = false,defaultValue = "0")Integer tag,
			@RequestParam(value = "type",required = false,defaultValue = "0") Integer type,
			@RequestParam(value = "mode",required = false,defaultValue = "0") Integer mode) {
		if(!tagService.CheckTagExist(tag))
			return Result.failure(ResultCode.TAG_NOT_EXIST);
		else
			return Result.success(courseService.OpenListCourseWithTagAndType(count, page, type, mode, tag));

	}
	
	@ApiOperation("管理员获取课程模板列表")
	@RequestMapping(value = "admin/templates/{page}/{count}",method = RequestMethod.GET)
	public Result AdminListTemplates(@PathVariable("page")Integer page,@PathVariable("count")Integer count,
			@RequestParam(value = "type",required = false,defaultValue = "0")Integer type) {
		return Result.success(courseService.ListCourseWithTagAndType(count, page,type,0,0, 0,
				0,0));
	}
	
	@ApiOperation("管理员根据课程id获取该课程的章节信息")
	@GetMapping(value = "admin/course/chapter/{id}")
	public Result AdminGetChaptersWithCourseId(@PathVariable(value = "id")Integer id) {
		if( !courseService.CheckCourseExist(id, false)) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			List<Chapter> chapters = chapterServiceImpl.GetChapterWithCourseId(id,false);
			return Result.success(chapters);
		}
	}
	
	@ApiOperation("用户根据课程id获取该课程的章节信息")
	@GetMapping(value = "open/course/chapter/{id}")
	public Result UserGetChaptersWithCourseId(@PathVariable(value = "id")Integer id) {
		if( !courseService.CheckCourseExist(id, true)) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			List<Chapter> chapters = chapterServiceImpl.GetChapterWithCourseId(id,true);
			return Result.success(chapters);
		}
	}
	
	@ApiOperation("用户获取课程的教学团队")
	@GetMapping("open/course/teachers/{id}")
	public Result UserGetCourseTeachers(@PathVariable("id")Integer id) {
		Course course = courseService.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			List<Map<String, Object>> teacherInfos =
					courseTeacherService.GetTeachersByCourseId(id,true);
			return Result.success(teacherInfos);
		}
	}

	@ApiOperation("管理员获取课程的教学团队")
	@GetMapping("admin/course/teachers/{id}")
	public Result AdminGetCourseTeachers(@PathVariable("id")Integer id) {
		Course course = courseService.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else {
			List<Map<String, Object>> teacherInfos =
					courseTeacherService.GetTeachersByCourseId(id,false);
			return Result.success(teacherInfos);
		}
	}
	
	@ApiOperation("为课程添加老师")
	@PostMapping("admin/course/teacher")
	public Result AddTeacherForCourse(@RequestBody()CourseTeacher data) {
		Course course = courseService.getById(data.getCourseId());
		TeacherInfo teacher = teacherService.GetTeacherInfo(data.getTeacherId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else if( teacher== null) {
			return Result.failure(ResultCode.TEACHER_NOT_EXIST);
		}
		else{
			if (courseTeacherService.CheckHasTeacher(data)) {
				return Result.failure(ResultCode.COURSE_ALREADY_HAS_TEACHER);
			}
			courseTeacherService.save(data);
			return Result.success(data);
		}
	}
	
	@ApiOperation("删除课程老师")
	@PostMapping("admin/course/teacher/del/{id}")
	public Result AddTeacherForCourse(@PathVariable("id")Integer id) {
		CourseTeacher courseTeacher = courseTeacherService.getById(id);
		if( courseTeacher== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		else{
			courseTeacherService.DeleteObjectById(id);
			return Result.success();
		}
	}
	

	@ApiOperation("获取当前有效的考试")
	@GetMapping(value = "open/course/examTest/{id}")
	public Result GetExamTestValidList(@PathVariable("id")Integer id) {
		Course course = courseService.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		return Result.success(examTestServiceImpl.GetExamTestValidListByCourseId(id));
	}
	
	@ApiOperation("发布公告")
	@PostMapping(value = "admin/course/notice")
	public Result PublishNotice(@RequestBody()CourseNotice notice) {
		Course course = courseService.getById(notice.getCourseId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		return Result.success(courseNoticeServiceImpl.AddNotice(notice));
	}
	
	@ApiOperation("删除公告")
	@PostMapping(value = "admin/course/notice/del/{id}")
	public Result DeleteNotice(@PathVariable("id")Integer id) {
		CourseNotice notice = courseNoticeServiceImpl.getById(id);
		if( notice== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		return Result.success(courseNoticeServiceImpl.DeleteNotice(id));
	}
	
	@ApiOperation("获取所有公告")
	@GetMapping(value = "open/course/notice/{page}/{count}")
	public Result GetNotices(@PathVariable("page")Integer page,@PathVariable("count")Integer count,@RequestParam("courseId")Integer courseId) {
		Course course = courseService.getById(courseId);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		return Result.success(courseNoticeServiceImpl.GetNotices(page, count, courseId));
	}
	
	
	@ApiOperation("新增课程成员信息")
	@PostMapping("admin/course/member")
	public Result AddCourseMember(@RequestBody()CourseMember data) {
		Course course = courseService.getById(data.getCourseId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		course.setState(CourseState.WAITING_SUBMIT.getValue());
		courseService.ChangeObjectState(course.getId(), CourseState.WAITING_SUBMIT.getValue());
		CourseMember res = this.courseMemberServiceImpl.AddCourseMember(data);
		if (res !=null) {
			return Result.success(data);
		}
		return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
	}
	
	@ApiOperation("修改课程成员信息")
	@PostMapping("admin/course/member/update")
	public Result UpdateCourseMember(@RequestBody()CourseMember data) {
		Course course = courseService.getById(data.getCourseId());
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		courseService.ChangeObjectState(course.getId(), CourseState.WAITING_SUBMIT.getValue());
		CourseMember res = this.courseMemberServiceImpl.GetCourseMemberById(data.getId());
		if (res == null) {
			return Result.failure(ResultCode.COURSE_MEMBER_NOT_EXIST);
		}
		if (courseMemberServiceImpl.UpdateCourseMember(data)) {
			return Result.success(data);
		}
		return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
	}
	
	
	@ApiOperation("管理员获取指定课程所有成员")
	@GetMapping(value = "admin/course/member/{page}/{count}")
	public Result GetCourseMembers(@PathVariable("page")Integer page,@PathVariable("count")Integer count,@RequestParam("courseId")Integer courseId) {
		Course course = courseService.getById(courseId);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		return Result.success(courseMemberServiceImpl.ListCourseMembers(page, count,courseId, false));
	}
	
	@ApiOperation("用户获取指定课程所有成员")
	@GetMapping(value = "open/course/member/{id}")
	public Result UserGetCourseMembers(@PathVariable("id")Integer id) {
		Course course = courseService.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		return Result.success(courseMemberServiceImpl.GetAllMembersByCourseId(id));
	}

	@ApiOperation("删除指定课程成员")
	@PostMapping(value = "admin/course/member/del/{id}")
	public Result DeleteCourseMember(@PathVariable("id")Integer id) {
		CourseMember course = courseMemberServiceImpl.getById(id);
		if( course== null) {
			return Result.failure(ResultCode.COURSE_MEMBER_NOT_EXIST);
		}
		courseService.ChangeObjectState(course.getCourseId(), CourseState.WAITING_SUBMIT.getValue());
		return Result.success(courseMemberServiceImpl.DeleteCourseMember(id));
	}
	
	
	@ApiOperation("新增课程文档信息")
	@PostMapping("admin/course/doc")
	public Result AddCourseDoc(@RequestBody()VrLessonDocument data) {
		VrLesson lesson = vrLessonServiceImpl.getById(data.getVrLessonId());
		System.out.print(JSonUtil.toJson(data));
		if( lesson== null) {
			return Result.failure(ResultCode.VR_LESSON_COURSE_NOT_EXIST);
		}
		VrLessonDocument res = this.vrLessonDocumentServiceImpl.AddVrLessonDocument(data);
		if (res !=null) {
			return Result.success(data);
		}
		return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
	}
	
	@ApiOperation("修改课程文档信息")
	@PostMapping("admin/course/doc/update")
	public Result UpdateCourseDoc(@RequestBody()VrLessonDocument data) {
		VrLesson lesson = vrLessonServiceImpl.getById(data.getVrLessonId());
		
		if( lesson== null) {
			return Result.failure(ResultCode.VR_LESSON_COURSE_NOT_EXIST);
		}
		VrLessonDocument res = this.vrLessonDocumentServiceImpl.GetVrLessonDocumentById(data.getId());
		if (res == null) {
			return Result.failure(ResultCode.COURSE_MEMBER_NOT_EXIST);
		}
		if (vrLessonDocumentServiceImpl.UpdateVrLessonDocument(data)) {
			return Result.success(data);
		}
		return Result.failure(ResultCode.SYSTEM_DATABASE_ERROR);
	}
	
	
	@ApiOperation("管理员获取指定课程所有文档")
	@GetMapping(value = "admin/course/doc/{page}/{count}")
	@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_TEACHING','ROLE_COURSE')")
	public Result GetCourseDocs(@PathVariable("page")Integer page,@PathVariable("count")Integer count,@RequestParam("lessonId")Integer lessonId) {
		VrLesson lesson = vrLessonServiceImpl.getById(lessonId);
		if( lesson== null) {
			return Result.failure(ResultCode.VR_LESSON_COURSE_NOT_EXIST);
		}
		return Result.success(vrLessonDocumentServiceImpl.ListVrLessonDocument(page, count,lessonId, false));
	}
	
	@ApiOperation("获取指定课程所有文档")
	@GetMapping(value = "open/course/doc/{id}")
	public Result UserGetCourseDocs(@PathVariable("id")Integer id) {
		VrLesson lesson = vrLessonServiceImpl.getById(id);
		if( lesson== null) {
			return Result.failure(ResultCode.VR_LESSON_COURSE_NOT_EXIST);
		}
		return Result.success(vrLessonDocumentServiceImpl.GetAllVrLessonDocumentByLessonId(id));
	}
	
	@ApiOperation("删除指定课程文档")
	@PostMapping(value = "admin/course/doc/del/{id}")
	public Result DeleteCourseDoc(@PathVariable("id")Integer id) {
		VrLesson lesson = vrLessonServiceImpl.getById(id);
		
		if( lesson== null) {
			return Result.failure(ResultCode.VR_LESSON_COURSE_NOT_EXIST);
		}
		return Result.success(vrLessonDocumentServiceImpl.DeleteVrLessonDocument(id));
	}
	@ApiOperation("提交课程到审核")
	@PostMapping("admin/course/submit/{id}")
	public Result SubmitToReview(Integer id) {
		Course course = courseService.getById(id);
		if (course == null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		courseService.ChangeObjectState(id, CourseState.WAITING_REVIEW.getValue());
		return Result.success();
	}
	@ApiOperation("取消审核")
	@PostMapping("admin/course/cancel/{id}")
	public Result CancelReview(Integer id) {
		Course course = courseService.getById(id);
		if (course == null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		courseService.ChangeObjectState(id, CourseState.WAITING_SUBMIT.getValue());
		return Result.success();
	}
	@ApiOperation("审核通过")
	@PostMapping("admin/course/review/pass/{id}")
	public Result ReviewPass(Integer id) {
		Course course = courseService.getById(id);
		if (course == null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		courseService.ChangeObjectState(id, CourseState.SUCCESS.getValue());
		return Result.success();
	}
	@ApiOperation("审核失败")
	@PostMapping("admin/course/review/reject/{id}")
	public Result ReviewReject(Integer id) {
		Course course = courseService.getById(id);
		if (course == null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		courseService.ChangeObjectState(id, CourseState.FAILED.getValue());
		return Result.success();
	}
	
	@ApiOperation("发布课程")
	@PostMapping("admin/course/publish/{id}")
	public Result PublishReject(Integer id) {
		Course course = courseService.getById(id);
		if (course == null) {
			return Result.failure(ResultCode.COURSE_NOT_EXIST);
		}
		courseService.ChangeObjectState(id, CourseState.ONLINE.getValue());
		return Result.success();
	}
	
	@ApiOperation("获取推荐课程")
	@GetMapping("open/course/recommend")
	public Result GetRecommondCourses(@RequestParam()Integer count) {
		if (count<0) {
			return Result.failure(ResultCode.PARAM_IS_INVALID);
		}
		else {
			return Result.success(courseService.GetRecommondCourseList(count));
		}
	}
	
}

